#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author:Zx
@file: hikes.py
@time: 2025/7/23  10:44
# @describe: 路线
"""
from flask import Blueprint, render_template, request, jsonify, redirect, url_for, current_app
from flask_login import login_required, current_user
from werkzeug.exceptions import InternalServerError

from app import load_messages
from config import Config
from utils.data_utils import load_data, save_data, update_visit_stats, get_user_count, get_provinces, get_level
import logging
import os
import uuid
from datetime import date, datetime
from models.announcement import AnnouncementManager

announcement_manager = AnnouncementManager()

hikes_bp = Blueprint('hikes', __name__)


# 获取待审核路线数量
def get_pending_hikes_count():
    hikes = load_data('hikes.json')
    return sum(1 for hike in hikes if hike.get('status') == 'pending')


# 获取待审核路线列表
def get_pending_hikes():
    hikes = load_data('hikes.json')
    return [hike for hike in hikes if hike.get('status') == 'pending']


@hikes_bp.route('/')
@login_required
def index():
    try:
        visit_count = update_visit_stats()
        user_count = get_user_count()
        hikes = [h for h in load_data('hikes.json') if h.get('status') == 'approved']
        pending_hikes = get_pending_hikes() if current_user.role == 'admin' else []
        pending_hikes_count = get_pending_hikes_count()

        provinces = get_provinces()
        levels = get_level()

        # 计算待审核评论数量
        comments = load_data('comments.json')
        pending_comments_count = sum(1 for c in comments if c.get('status') == 'pending')

        # 计算待审核留言数量
        pending_messages_count = 0
        messages = load_messages()
        for msg in messages:
            if msg.get('status') == 'pending':
                pending_messages_count += 1
            for reply in msg.get('replies', []):
                if reply.get('status') == 'pending':
                    pending_messages_count += 1

        # 获取最新5条公告
        announcements = announcement_manager.get_all(limit=5)

        return render_template('index.html',
                               active_page='home',
                               hikes=hikes,
                               pending_hikes=pending_hikes,
                               pending_hikes_count=pending_hikes_count,
                               user_count=user_count,
                               visit_count=visit_count,
                               provinces=provinces,
                               levels=levels,
                               pending_comments_count=pending_comments_count,
                               pending_messages_count=pending_messages_count,
                               announcements=announcements)
    except Exception as e:
        logging.error(f'首页加载失败: {str(e)}', exc_info=True)
        return render_template('error.html', message='加载首页时发生错误', now=datetime.now()), 500


@hikes_bp.route('/hike/<int:hike_id>')
@login_required
def hike_detail(hike_id):
    try:
        hikes = load_data('hikes.json')
        comments = load_data('comments.json')

        hike = next((h for h in hikes if h['id'] == hike_id), None)
        if not hike:
            return render_template('error.html', message='路线不存在'), 404

        # 获取该路线下的所有评论
        hike_comments = [c for c in comments if c['hike_id'] == hike_id]

        # 如果不是管理员，只筛选已批准的评论
        if not current_user.is_authenticated or current_user.role != 'admin':
            hike_comments = [c for c in hike_comments if c.get('status') == 'approved']

        # 按时间倒序排序
        hike_comments.sort(key=lambda x: x['timestamp'], reverse=True)

        # 传递额外参数给模板，用于显示待审核评论数量
        pending_count = len([c for c in comments
                             if c['hike_id'] == hike_id
                             and c.get('status') == 'pending'])

        return render_template('hike_detail.html',
                               hike=hike,
                               comments=hike_comments,
                               pending_count=pending_count,
                               is_admin=current_user.role == 'admin')
    except Exception as e:
        logging.error(f'路线详情加载失败: {str(e)}', exc_info=True)
        return render_template('error.html', message='加载路线详情时发生错误', now=datetime.now()), 500


@hikes_bp.route('/add_hike', methods=['POST'])
@login_required
def add_hike():
    try:
        if 'image' not in request.files:
            return jsonify({'error': '未上传图片文件'}), 400

        image_file = request.files['image']
        if image_file.filename == '':
            return jsonify({'error': '未选择图片文件'}), 400

        # 生成唯一文件名
        filename = f"{uuid.uuid4()}{os.path.splitext(image_file.filename)[1]}"
        file_path = os.path.join(Config.UPLOAD_FOLDER, filename)
        image_file.save(file_path)

        # 处理装备数据
        equipment_str = request.form.get('equipment', '')
        equipment_list = [item.strip() for item in equipment_str.split('\n') if item.strip()]
        if not equipment_list:
            equipment_list = [item.strip() for item in equipment_str.split(',') if item.strip()]
        if not equipment_list and equipment_str:
            equipment_list = [equipment_str]

        # 创建新路线
        new_hike = {
            'name': request.form.get('name'),
            'image': filename,
            # pending, approved, rejected
            'status': 'pending' if current_user.role == 'user' else 'approved',
            # 提交用户ID
            'submitted_by': current_user.id,
            'submitted_by_username': current_user.username,
            'submitted_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            # 审核管理员ID
            'approved_by': None,
            'approved_at': None,
            'description': request.form.get('description'),
            'address': request.form.get('address'),
            'route': request.form.get('route'),
            'duration': request.form.get('duration'),
            'length': request.form.get('length'),
            'best_time': request.form.get('best_time'),
            'difficulty': request.form.get('difficulty'),
            'score': float(request.form.get('score')),
            'equipment': equipment_list,
            'two_step_map_url': request.form.get('two_step_map_url')
        }

        # 验证必填字段
        required_fields = ['name', 'description', 'address', "route", 'duration', 'length',
                           'best_time', 'difficulty', 'score', 'equipment', 'two_step_map_url']
        if not all(new_hike.get(field) for field in required_fields):
            return jsonify({'error': '缺少必填字段'}), 400

        # 检查名称是否已存在
        hikes = load_data("hikes.json")
        name_lower = new_hike['name'].strip().lower()
        if any(h['name'].strip().lower() == name_lower for h in hikes):
            return jsonify({'error': '徒步路线已存在'}), 400

        # 设置ID并保存
        new_hike['id'] = len(hikes) + 1
        hikes.append(new_hike)
        save_data(hikes, "hikes.json")

        # 记录用户添加 - 如果是普通用户，增加待审核计数
        if current_user.role == 'user':
            current_user.pending_submissions += 1
            current_user.record_data_add()
            current_user._save_user_data()

        return jsonify({
            'message': '路线提交成功' if current_user.role == 'user' else '路线添加成功',
            'needs_approval': current_user.role == 'user',
            'hike': new_hike
        }), 201
    except Exception as e:
        logging.error(f'添加路线失败: {str(e)}', exc_info=True)
        return jsonify({'error': '服务器内部错误'}), 500


@hikes_bp.route('/check_add_limit', methods=['GET'])
@login_required
def check_add_limit():
    try:
        if current_user.role == 'admin':
            return jsonify({
                'success': True,
                'can_add': True,
                'message': '管理员无限制',
                'remaining': '无限制'
            })
        max_daily = current_app.config['MAX_DAILY_ADDITIONS']
        today_count = current_user.get_today_add_count()
        can_add = today_count < max_daily
        remaining = max_daily - today_count

        # 在达到限制时返回403状态码和错误信息
        if not can_add:
            return jsonify({
                'success': False,
                'can_add': False,  # 明确添加 can_add 字段
                'error': '达到添加限制',
                'message': f'今日已达到添加限制({max_daily}条)',
                'today_count': today_count,
                'max_daily': max_daily
            }), 403  # 添加403状态码

        # 在可以添加时返回正常响应
        return jsonify({
            'success': True,
            'can_add': True,
            'message': f'今日已添加 {today_count} 条，还可添加 {remaining} 条',
            'remaining': remaining,
            'max_daily': max_daily
        })
    except Exception as e:
        logging.error(f'检查添加限制失败: {str(e)}', exc_info=True)
        return jsonify({
            'success': False,
            'message': '检查添加限制时出错'
        }), 500


@hikes_bp.route('/api/hikes', methods=['GET'])
@login_required
def filter_hikes():
    try:
        province = request.args.get('province', '')
        level = request.args.get('level', '')
        search = request.args.get('search', '').strip()

        filtered_hikes = []
        hikes_data = load_data('hikes.json')

        for hike in hikes_data:
            province_match = not province or (province in hike.get('address', ''))
            level_match = not level or (level == hike.get('difficulty', ''))
            name_match = not search or (search.lower() in hike.get('name', '').lower())

            if province_match and level_match and name_match:
                filtered_hikes.append(hike)

        return jsonify({
            'success': True,
            'data': filtered_hikes,
            'count': len(filtered_hikes)
        })
    except Exception as e:
        logging.error(f'筛选路线失败: {str(e)}', exc_info=True)
        return jsonify({'success': False, 'error': str(e)}), 500


# 线路审核
# 统一路由格式，合并approve和reject为一个路由
@hikes_bp.route('/admin/hike/<int:hike_id>/<action>', methods=['POST'])
@login_required
def review_hike(hike_id, action):
    if current_user.role != 'admin':
        return jsonify({'success': False, 'message': '无权操作'}), 403

    try:
        hikes = load_data('hikes.json')
        hike = next((h for h in hikes if h['id'] == hike_id), None)

        if not hike:
            return jsonify({'success': False, 'message': '路线不存在'}), 404

        if action == 'approve':
            hike['status'] = 'approved'
            message = '路线已批准'
        elif action == 'reject':
            hike['status'] = 'rejected'
            message = '路线已拒绝'
        else:
            return jsonify({'success': False, 'message': '无效操作'}), 400

        hike['approved_by'] = current_user.id
        hike['approved_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        save_data(hikes, 'hikes.json')
        return jsonify({'success': True, 'message': message}), 200
    except Exception as e:
        logging.error(f'操作失败: {str(e)}', exc_info=True)
        return jsonify({'success': False, 'message': '服务器内部错误'}), 500


@hikes_bp.route('/api/top10_hiking_routes', methods=['GET'])
@login_required
def top10_hiking_routes():
    try:
        routes = load_data('top10_hiking_routes.json')
        return render_template('top10_hiking_routes.html', routes=routes, active_page='top10_hiking_routes')
    except Exception as e:
        logging.error(f'经典路线榜单-加载失败: {str(e)}', exc_info=True)
        return render_template('error.html', message='加载-经典路线榜单-发生错误', now=datetime.now()), 500
